#!/usr/bin/env python
#
# logdelta: Read list of log messages with
# time data, and format with time deltas.
#
# Also, you can show the times relative to a fixed point.
#
# Copyright 2003,2010 Sony Corporation
#
# To do:
#  * allow choosing delta as 'time to next' vs. 'time from last'
#    current code is 'time to next'
#

import sys
import string

def usage():
	print """usage: logdelta [<options>] <filename>

This program parses the output from a set of andoid log message lines which
have time data prefixed because the 'time' option is used
When run with no options, the time information is converted to show the
time delta between each message line and the next.  When run with the
'-b' option, all times are relative to a single (base) point in time.

Options:
  -h            Show this usage help.
  -b <base>	Specify a base for time references.
		<base> can be a number or a string.
		If it is a string, the first message line
		which matches (somewhere in the line) is used
                as the time reference.
  -x            Swap absolute time and delta time in output
  -p            Show delta time from previous line instead of
                to next line

ex: $ logcat -d -v time >logfile
    $ logdelta -b start logfile

will show times relative to the first line in the log output
that has the string "start" in it.
"""
	sys.exit(1)

# returns a tuple containing the seconds and text for each message line
# seconds is returned as a float
# raise an exception if no timing data was found
# average line looks like:
# 01-01 00:00:42.409 I/PackageManager(  769): Parsing package in file: /data/app/CtsAppWithData.apk
def get_time(line):
	# FIXTHIS - should validate that lines start with time prefix

	# split on closing bracket
	time_str = line[6:18]
	(h, m, s) = string.split(time_str, ":")
	time = int(h)*3600+int(m)*60+string.atof(s)
	rest = line[18:]

	if rest[-1]=='\n':
		rest = rest[:-1]
	if rest[-1]=='\r':
		rest = rest[:-1]

	#print "time=", time
	#print "rest='%s'" % rest
	return (time, rest)


def main():
	base_str = ""
	filein = ""
	rel_first = 0
	prev_delta = 0
	for arg in sys.argv[1:]:
		if arg=="-b":
			base_str = sys.argv[sys.argv.index("-b")+1]
		elif arg=="-x":
			rel_first = 1
		elif arg=="-p":
			prev_delta = 1
		elif arg=="-h":
			usage()
		else:
			filein = arg

	if not filein:
		usage()

	try:
		lines = open(filein,"r").readlines()
	except:
		print "Problem opening file: %s" % filein
		sys.exit(1)

	if base_str:
		print 'base= "%s"' % base_str
		# assume a numeric base.  If that fails, try searching
		# for a matching line.
		try:
			base_time = float(base_str)
		except:
			# search for line matching <base> string
			found = 0
			for line in lines:
				try:
					(time, rest) = get_time(line)
				except:
					continue
				if string.find(rest, base_str)!=-1:
					base_time = time
					found = 1
					# stop at first match
					break
			if not found:
				print 'Couldn\'t find line matching base pattern "%s"' % base_str
				sys.exit(1)
		
		# print out lines with time relative to base_time
		for line in lines:
			try:
				(time, rest) = get_time(line)
			except:
				# if any problem parsing time, don't convert anything
				print line
				continue

			# show time from base
			delta = time-base_time
			if rel_first:
				print "%5.3f [ %5.3f ]" % (delta, time) + \
					rest
			else:
				print "%5.3f < %5.3f >" % (time, delta) + \
					rest
	elif prev_delta:
		# print out lines with time relative to previous line
		prev_time = 0.0
		for line in lines:
			try:
				(time, rest) = get_time(line)
			except:
				# if any problem parsing time, don't convert anything
				time = prev_time
				rest = line

			# just show time from last line
			delta = time - prev_time
			if rel_first:
				print "%5.3f [ %5.3f ] %s" % (delta, prev_time, rest)
			else:
				print "%5.3f < %5.3f > %s" % (prev_time, delta, rest)

			prev_time = time
	else:
		# no base time, not prev_delta
		# do time to next line
		last_time = 0.0
		last_rest = ""
		# print out lines with time relative to next line
		for line in lines:
			try:
				(time, rest) = get_time(line)
			except:
				# if any problem parsing time, don't convert anything
				time = last_time
				rest = line

			# just show time from last line
			delta = time - last_time
			if last_rest:
				if rel_first:
					print "%5.3f [ %5.3f ]" % (delta, last_time) + \
						last_rest
				else:
					print "%5.3f < %5.3f >" % (last_time, delta) + \
						last_rest
			last_time = time
			last_rest = rest

		if rel_first:
			print "????? [ %5.3f ]" % (time) + rest
		else:
			print "%5.3f < ????? >" % (time) + rest
			
main()

